Cloud Firestore
データモデル的にしっくり来そうなのでこっちにすることにした
Scrapboxをバックエンドにする案はやめた
Scrapboxはやはり人間とのインターフェイスであって、機械的なデータを置くべきではない
「コレクション」の中に「ドキュメント」がある仕組み
ドキュメントはJSONだと思えば良い(+データ型がいくつか追加されてる)
ドキュメントは1MBまで
ドキュメントの中にまたコレクションを入れることはできる
ドキュメントの中にマップや配列、参照が入れられる
テキスト
UTF-8 表現の最初の 1,500 バイトのみがクエリによって考慮されます。
単独フィールドに対するインデックスは自動で生成されるが長文テキストはインデックスが無意味なので明示的に除外したほうがよい(課金的な意味で)
doc("...").set(...)で上書き(なければ作成)
collectionsRef.doc("hoge").set(...)でID指定で作成できる
collectionRef.add(...)でID自動生成で追加できる
ref = collections.doc() してから ref.set(data)が良さそう
{timestamp: firebase.firestore.FieldValue.serverTimestamp()}を入れておくと良さげ
オフラインで書くことがあるからcreatedは手元のタイムスタンプを入れたほうが良さげ
書き込み命令はPromiseを返して、完了時にthenが呼ばれる
オフラインで書き込みをするとオンラインに戻ってサーバに書き込めた時点でthenが呼ばれる
なのでこれをウォッチして「書き込み済み」マークを表示するのが良さそう
それと別にsnapshot.metadata.hasPendingWritesで未完了の書き込みの有無がわかる
docRef.updateもあるぞ?merge:trueと何が違うんだ?
存在しないドキュメントをgetしてもエラーにはならない
空のオブジェクトが帰ってくる
doc.exists() => false
.onSnapshot(function(querySnapshot) {
更新をlistenする
一度に500件
batch = db.batch()に対して操作をしてからbatch.commit()
オフラインの永続性
ユーザーが同じ Cloud Firestore データベースを参照する複数のブラウザタブを開き、オフラインの永続性が有効になっている場合、Cloud Firestore は最初のタブでのみ正しく動作します。
それはうっかりミスで複数タブ開いてデータをとばしそうで怖いな
サンプルコードを見ると一応検出できるっぽいので、ユーザに警告すべきだな
Wifiを切って書き込んだものがWifi再接続後にサーバに保存されるのを確認した
接続があってもなくてもsnapshot.metadataはfromCache: false
一方でブラウザをリロードした時にはfromCache: trueである
Python API
Pythonではcollection.doc()ではなくcollection.document()
DocRef#getはdocument.DocumentSnapshotを返す
.to_dict()で辞書になる
db.collection("...").get()が「すべてのドキュメントを返す」と書いてあって、マジかと思ったがジェネレータが作成されるので安心
DeprecationWarning: 'Collection.get' is deprecated: please use 'Collection.stream' instead.
xs.__next__() # => document.DocumentSnapshot
条件をつける時にはwhereを使う
code:python
In 25: [d.to_dict()"text" for d in db.collection("pieces").where("text", "<", "t").stream()] In 26: [d.to_dict()"text" for d in db.collection("pieces").where("text", ">", "t").stream()] Web JS API
まずscriptタグでいくつかのJSを読み、それから設定する
ローカルファイルシステムから開いたのでは動かないJSがあるそうだ
firebase-toolsでサーブする
Pythonのhttp.serverでも良いと思うがまずは言われた通りにしてみることにした
Error: Cannot understand what targets to deploy. Check that you specified valid targets if you used the --only or --except flag. Otherwise, check your firebase.json to ensure that your project is initialized for the desired features.
うーむ
$ python3 -m http.server
で特に問題なさそうだ
JSの場合、setやgetはPromiseを返してくる
code:js
db.collection("pieces").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(${doc.id} => ${doc.data()["text"]});
});
});
REST API